package com.xjj.datarources.controller;

import cn.hutool.json.JSONObject;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.xjj.datarources.base.DBContextHandler;
import com.xjj.datarources.common.ResultCode;
import com.xjj.datarources.common.ResultVo;
import com.xjj.datarources.config.MyAckReceiver;
import com.xjj.datarources.dao.DataSourceMapper;
import com.xjj.datarources.dao.SQLMapper;
import com.xjj.datarources.pojo.QueryPoJo;
import com.xjj.datarources.pojo.UserInfo;
import com.xjj.datarources.service.*;
import com.xjj.datarources.vo.Admininfo;
import com.xjj.datarources.vo.MysqlVo;
import com.xjj.datarources.vo.QueryVo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.UnauthorizedException;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @name: xjj
 * @date: 2021/5/20 9:19
 */
@Controller
@RequestMapping
public class QueryController {

    private final static Log log = LogFactory.get();

    @Resource
    private SQLMapper mapper;


    @Resource
    private MysqlVoService mysqlVoService;

    @Resource
    private DBChangeService dbChangeService;

    @Resource
    private QueryPoJoService queryPoJoService;

    @Resource
    private QueryVoService queryVoService;

    @Resource
    private UserInfoService userInfoService;

    @Resource
    private MQService mqService;

    @Resource
    private MyAckReceiver myAckReceiver;

    @GetMapping("/mysql")
    @RequiresPermissions("mysql:view")
    @ResponseBody
    public IPage<MysqlVo> getId(){
        DBContextHandler.clearDataSource();
        dbChangeService.changeDb("1");
        log.info("当前数据源为:{}", DBContextHandler.getDataSource());
        return mysqlVoService.getMysqlPage();
    }

    @GetMapping("/sqlserver")
    @RequiresPermissions("userInfo:view")
    @ResponseBody
    public List<Admininfo> getName(){
        //log.info("切换前数据源为:{}",DBContextHandler.getDataSource() );
        dbChangeService.changeDb("2");
        log.info("切换后数据源为:{}", DBContextHandler.getDataSource());
        return mapper.getIds();
    }

    @GetMapping("/up/{id}")
    @ResponseBody
    //@Transactional
    public String update(@PathVariable String id){
        dbChangeService.changeDb("1");
        log.info("当前数据源为:{}", DBContextHandler.getDataSource());

        return mysqlVoService.updateNameById(id);
    }

    //@GetMapping("/login")
    //@ResponseBody
    public Map<String, Object> login(HttpServletRequest request, Map<String, Object> map) throws Exception{
        //System.out.println("HomeController.login()");
        // 登录失败从request中获取shiro处理的异常信息。
        // shiroLoginFailure:就是shiro异常类的全类名.

        String exception = (String) request.getAttribute("shiroLoginFailure");
        //System.out.println("exception=" + exception);
        String msg = "";
        if (exception != null) {
            if (UnknownAccountException.class.getName().equals(exception)) {
                System.out.println("UnknownAccountException -- > 账号不存在：");
                msg = "UnknownAccountException -- > 账号不存在：";
            } else if (IncorrectCredentialsException.class.getName().equals(exception)) {
                System.out.println("IncorrectCredentialsException -- > 密码不正确：");
                msg = "IncorrectCredentialsException -- > 密码不正确：";
            } else if ("kaptchaValidateFailed".equals(exception)) {
                System.out.println("kaptchaValidateFailed -- > 验证码错误");
                msg = "kaptchaValidateFailed -- > 验证码错误";
            } else {
                msg = "else >> "+exception;
                System.out.println("else -- >" + exception);
            }
        }
        map.put("msg", msg);
        // 此方法不处理登录成功,由shiro进行处理
        //return "/login";
        return map;
    }


    //
    @GetMapping("/query")
    @ResponseBody
    public List<Map<String, Object>> query(@RequestParam("sql") String sql,String id){


        /**
         * sql语句会存储到某张表里，该表再通过一对多来进行参数替换
         */
        //String sql = "select empno, empname from ba_admininfo where empname like @empname";

        dbChangeService.changeDb("1");

        QueryVo queryVo = queryVoService.getById(id);
        String temp = "";
        for (QueryPoJo queryPoJo : queryVo.getQueryPoJos()){
            //queryVo.setQuerySql(queryVo.getQuerySql().replace(queryPoJo.getField(), queryPoJo.getValue()));
            temp = sql.replace(queryPoJo.getField(), queryPoJo.getValue());
            sql = temp;
        }

        dbChangeService.changeDb("2");
//        queryVo.getQuerySql()
        return mapper.query(temp);



    }


    @GetMapping("/login")
    @ResponseBody
    public ResultVo login(String username, String password){

        Map<String, Object> data = new HashMap<>();

        UsernamePasswordToken usernamePasswordToken = null;
        try {
            usernamePasswordToken = new UsernamePasswordToken(username, password);
            Subject subject = SecurityUtils.getSubject();

            subject.login(usernamePasswordToken);
            if (subject.isAuthenticated()) {
                data.put("session", subject.getSession().getId());
                return new ResultVo(ResultCode.SUCCESS, data);
            } else {
                data.put("msg", "鉴权失败");
                return new ResultVo(ResultCode.FAILED, data);
            }
        } catch (IncorrectCredentialsException | UnknownAccountException e){
            return new ResultVo(ResultCode.USER_NOT_LOGIN);
        }catch (LockedAccountException e){
            return new ResultVo(ResultCode.USER_ERROR_OR_PASSWORD_ERROR);
        }catch (Exception e){
            return new ResultVo(ResultCode.SYSTEM_ERR);
        }

    }

    @GetMapping("/logout")
    @ResponseBody
    public ResultVo logout(){
        log.info("退出登录");
        dbChangeService.changeDb("1");
        log.info("切换数据源成功");
        SecurityUtils.getSubject().logout();
        return new ResultVo(ResultCode.USER_OUT);
    }

    @GetMapping(value = "/userList")
    @RequiresPermissions("userInfo:view") // 权限管理
    @ResponseBody
    public Map<String, Object> findUserInfoByUsername() {
        UserInfo userInfo = (UserInfo) SecurityUtils.getSubject().getPrincipal();
        Map<String, Object> data = new HashMap<>();
        data.put("code", 400);
        data.put("users", userInfoService.findAll());
        data.put("登录用户", userInfo);
        return data;
        //return userInfoService.findByUsername(username);
    }



    @GetMapping("/mq")
    @ResponseBody
    public String sendMsg(){
        mqService.sendWork();
        //mqService.sendTopic();

        return "success";
    }

    @GetMapping("/xf")
    @ResponseBody
    public String getMsg(){
        //myAckReceiver.onMessage();
        return "xf";
    }






}
